<!-- Statistics -->
<div id="blocksStats" class="row">

    <!-- Total Blocks Mined -->
    <div class="col-lg-3 col-sm-4">
        <div class="infoBox hoverExpandEffect">
            <div class="icon">
                <span class="fa fa-cubes"></span>
            </div>
            <div class="content">
                <div class="text">Total Blocks Mined</div>
                <div class="value"><span id="blocksTotal"></span> <span class="smallText">(Last: <span id="lastBlockFound"></span>)</span></div>
            </div>
        </div>
    </div>

    <!-- Maturity Depth Requirement -->
    <div class="col-lg-3 col-sm-4">
        <div class="infoBox hoverExpandEffect">
            <div class="icon">
                <span class="fa fa-unlock-alt"></span>
            </div>
            <div class="content">
                <div class="text">Maturity Requirement</div>
                <div class="value"><span id="blocksMaturityCount"></span></div>
            </div>
        </div>
    </div>

    <!-- Efficiency -->
    <div class="col-lg-3 col-sm-4">
        <div class="infoBox hoverExpandEffect">
            <div class="icon">
                <span class="fa fa-line-chart"></span>
            </div>
            <div class="content">
                <div class="text">Efficiency</div>
                <div class="value"><span id="efficiency"></span></div>
            </div>
        </div>
    </div>
    
    <!-- Average Luck -->
    <div class="col-lg-3 col-sm-4">
        <div class="infoBox hoverExpandEffect">
            <div class="icon">
                <span class="fa fa-line-chart"></span>
            </div>
            <div class="content">
                <div class="text">Average Luck</div>
                <div class="value"><span id="averageLuck"></span></div>
            </div>
        </div>
    </div>
    
</div>

<!-- Report -->
<div id="blocksReport" class="table-responsive">
    <table class="table table-hover table-striped">
        <thead>
        <tr>
            <th class="col1">Time Found</th>
            <th class="col2">Reward</th>
            <th class="col3">Height</th>
            <th class="col4">Difficulty</th>
            <th class="col5">Block Hash</th>
            <th class="col6">Effort</th>
            <th class="col7" title="How many more blocks network must mine before this block is matured">Status</th>
        </tr>
        </thead>
        <tbody id="blocksReport_rows">
        </tbody>
    </table>
</div>

<p class="text-center">
    <button type="button" class="btn btn-default" id="loadMoreBlocks">Load More</button>
</p>

<!-- Javascript -->
<script>
function formatLuck(difficulty, shares) {
    // Only an approximation to reverse the calculations done in pool.js, because the shares with their respective times are not recorded in redis
    // Approximation assumes equal pool hashrate for the whole round
    // Could potentially be replaced by storing the sum of all job.difficulty in the redis db.
    if (lastStats.config.slushMiningEnabled) {
        // Uses integral calculus to calculate the average of a dynamic function
        var accurateShares = 1/lastStats.config.blockTime * (  // 1/blockTime to get the average
            shares * lastStats.config.weight * (                  // Basically calculates the 'area below the graph' between 0 and blockTime
                1 - Math.pow( 
                    Math.E, 
                    ((- lastStats.config.blockTime) / lastStats.config.weight)  // blockTime is equal to the highest possible result of (dateNowSeconds - scoreTime)
                )
            )
        );
    }
    else {
        var accurateShares = shares;
    }
        
    var percent = Math.round(accurateShares / difficulty * 100);
    if(!percent){
        return '<span class="luckGood">?</span>';
    }
    else if(percent <= 100){
        return '<span class="luckGood">' + percent + '%</span>';
    }
    else if(percent >= 101 && percent <= 150){
        return '<span class="luckMid">' + percent + '%</span>';
    }
    else{
        return '<span class="luckBad">' + percent + '%</span>';
    }    
}

function formatEfficiency(percent) {
    return percent + '%';
}

    
currentPage = {
    destroy: function(){
        if (xhrGetBlocks) xhrGetBlocks.abort();
    },
    update: function(){
        updateText('blocksTotal', lastStats.pool.totalBlocks.toString());
        if (lastStats.pool.lastBlockFound) {
            var d = new Date(parseInt(lastStats.pool.lastBlockFound)).toISOString();
            $('#lastBlockFound').timeago('update', d);
        }
        else {
            $('#lastBlockFound').removeAttr('title').data('ts', '').update('Never');
        }
        updateText('blocksMaturityCount', lastStats.config.depth.toString());

        $('#efficiency').html(formatEfficiency(lastStats.pool.efficiency));
        $('#averageLuck').html(formatLuck(lastStats.pool.totalDiff, lastStats.pool.totalShares));

        renderBlocks(lastStats.pool.blocks);	
    }
};

var xhrGetBlocks;
$('#loadMoreBlocks').click(function(){
    if (xhrGetBlocks) xhrGetBlocks.abort();
    xhrGetBlocks = $.ajax({
        url: api + '/get_blocks',
        data: {
            height: $('#blocksReport_rows').children().last().data('height')
        },
        dataType: 'json',
        cache: 'false',
        success: function(data){
            renderBlocks(data);
        }
    });
});

function parseBlock(height, serializedBlock){
    var parts = serializedBlock.split(':');
    var block = {
        height: parseInt(height),
        hash: parts[0],
        time: parts[1],
        difficulty: parseInt(parts[2]),
        shares: parseInt(parts[3]),
        orphaned: parts[4],
        reward: parts[5]
    };

    var toGo = lastStats.config.depth - (lastStats.network.height - block.height);
    if(toGo > 1){
        block.maturity = toGo + ' to go';
    } 
    else if(toGo == 1){
        block.maturity = "<i class='fa fa-spinner fa-spin'></i>";
    } 
    else if(toGo <= 0){
        block.maturity = "<i class='fa fa-unlock-alt'></i>";
    }
        
    switch (block.orphaned){
        case '0':
            block.status = 'unlocked';
            block.maturity = "<i class='fa fa-unlock-alt'></i>";
            break;
       case '1':
            block.status = 'orphaned';
            block.maturity = "<i class='fa fa-times'></i>";
            block.reward = 0;
            break;
        default:
            block.status = 'pending';
            break;
    }
    return block;
}

function getBlockRowElement(block, jsonString){        
    function formatBlockLink(hash){
        return '<a target="_blank" href="' + getBlockchainUrl(hash) + '">' + hash + '</a>';
    }

    var blockStatusClasses = {
        'pending': 'pending',
        'unlocked': 'unlocked',
        'orphaned': 'orphaned'
    };
    
    var row = document.createElement('tr');
    row.setAttribute('data-json', jsonString);
    row.setAttribute('data-height', block.height);
    row.setAttribute('id', 'blockRow' + block.height);
    row.setAttribute('title', block.status);
    row.className = blockStatusClasses[block.status];
                
    var reward = "";    
    if(typeof block.reward == "undefined"){
        reward = "Waiting...";
    }
    else{
        reward = getReadableCoins(block.reward, 4, true);
    }
    
    var columns =
        '<td class="col1">' + formatDate(block.time) + '</td>' +
        '<td class="col2">' + reward + '</td>' +
        '<td class="col3">' + block.height + '</td>' +
        '<td class="col4">' + block.difficulty + '</td>' +
        '<td class="col5">' + formatBlockLink(block.hash) + '</td>' +
        '<td class="col6" title="' + block.shares + ' shares submitted">' + formatLuck(block.difficulty, block.shares) + '</td>' +
        '<td class="col7">' + block.maturity + '</td>';

    row.innerHTML = columns;
    
    return row;
}

function renderBlocks(blocksResults){
    var $blocksRows = $('#blocksReport_rows');

    for (var i = 0; i < blocksResults.length; i += 2){
        var block = parseBlock(blocksResults[i + 1], blocksResults[i]);
        var blockJson = JSON.stringify(block);
        
        var existingRow = document.getElementById('blockRow' + block.height);
        if (existingRow && existingRow.getAttribute('data-json') !== blockJson){
            $(existingRow).replaceWith(getBlockRowElement(block, blockJson));
        }
        else if (!existingRow){
            var blockElement = getBlockRowElement(block, blockJson);

            var inserted = false;
            var rows = $blocksRows.children().get();
            for (var f = 0; f < rows.length; f++) {
                var bHeight = parseInt(rows[f].getAttribute('data-height'));
                if (bHeight < block.height){
                    inserted = true;
                    $(rows[f]).before(blockElement);
                    break;
                }
            }
            if (!inserted){
                $blocksRows.append(blockElement);
            }
        }
    }
}
</script>
